﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO;
using System.IO.Compression;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Threading;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.Collections.Specialized;
using System.Net;

namespace AppPressFramework
{
    public class AppPressHandler
    {
        internal string GetTemporaryDirectory()
        {
            string tempFolder = Path.GetTempFileName();
            File.Delete(tempFolder);
            Directory.CreateDirectory(tempFolder);

            return tempFolder;
        }

        private HttpContext currentContext;
        public AppPressHandler(Object appLogic)
        {
            Log.Writeln("Request:" + HttpContext.Current.Request.Url.AbsoluteUri);
            if (AppPress.Settings == null)
                throw new Exception("AppPress not initialized. Call InitAppPress on Application load");
            try
            {
                currentContext = HttpContext.Current;

                if (currentContext.Request["getJs"] != null)
                {
                    currentContext.Response.ContentType = "text/javascript";
                    currentContext.Response.Cache.SetExpires(DateTime.UtcNow.AddSeconds(600));
                    currentContext.Response.Write(FileTexts.AppPressJS);
                }
                else if (currentContext.Request["getCSS"] != null)
                {
                    currentContext.Response.ContentType = "text/css";
                    currentContext.Response.Cache.SetExpires(DateTime.UtcNow.AddSeconds(600));
                    currentContext.Response.Write(FileTexts.AppPressCSS);
                }
                else if (currentContext.Request["UploadFile"] != null)
                {
                    try
                    {
                        if (currentContext.Request.Files.Count > 0)
                        {
                            string response = "";
                            int maxFileSizeInKB = 500;
                            if (currentContext.Request["MaxFileSizeInKB"] != null)
                                maxFileSizeInKB = int.Parse(currentContext.Request["MaxFileSizeInKB"]);
                            for (int i = 0; i < currentContext.Request.Files.Count; i++)
                            {
                                var fileName = currentContext.Request.Files[i].FileName;
                                var inputStream = currentContext.Request.Files[i].InputStream;
                                var intDocLen = currentContext.Request.Files[i].ContentLength;
                                if (maxFileSizeInKB != -1 && intDocLen > maxFileSizeInKB * 1024)
                                    throw new AppPressException("Maximum size of file that can be uploaded is " + maxFileSizeInKB + "KB");
                                if (currentContext.Request["DoNotSaveInDB"] != null)
                                {
                                    // Save in Temp Folder
                                    var uFileName = GetTemporaryDirectory() + "\\" + fileName;
                                    using (var fileStream = new FileStream(uFileName, FileMode.Create, FileAccess.Write))
                                    {
                                        inputStream.CopyTo(fileStream);
                                    }
                                    uFileName = uFileName.Replace('\\', '/');
                                    if (response.Length > 0)
                                        response += ",";
                                    response += string.Format("{{FileName:'{0}',Id:'{1}',Size:'{2}'}}", fileName, uFileName, (intDocLen / 1024) + " KB");
                                }
                                else
                                {
                                    // save in DB
                                    long fileId = -1;
                                    //long.TryParse(context.Request.Form["Filename"], out fileId);
                                    var fileType = AppPressLogic.GetFileType(System.IO.Path.GetExtension(fileName));
                                    FileUploadStorageType storageType = FileUploadStorageType.Database;
                                    string directory = currentContext.Request["Directory"];
                                    if (directory != null)
                                        storageType = FileUploadStorageType.Directory;
                                    EncryptionType? encryptionType = null;
                                    if (currentContext.Request["EncryptionType"] != null)
                                        encryptionType = (EncryptionType)Convert.ToInt16(currentContext.Request["EncryptionType"]);
                                    var docbuffer = new byte[intDocLen];
                                    inputStream.Read(docbuffer, 0, intDocLen);
                                    fileId = Util.SaveFile(storageType, directory, fileName, docbuffer, fileType, intDocLen, encryptionType);
                                    if (response.Length > 0)
                                        response += ",";
                                    response += string.Format("{{FileName:'{0}',Id:{1},Size:'{2}'}}", fileName, fileId, (intDocLen / 1024) + " KB");
                                }
                            }
                            currentContext.Response.Write("[" + response + "]");
                        }
                    }
                    catch (Exception exception)
                    {
                        currentContext.Response.Write(string.Format("{{Error:'{0}'}}", HttpUtility.JavaScriptStringEncode(exception.Message)));

                        // throw new Exception("<script>alert(" + exception.Message + ")</script>");
                    }
                    currentContext.Response.StatusCode = 200;
                }
                else if (currentContext.Request["EncryptTableColumn"] != null)
                {
                    throw new NotImplementedException();
                    if (currentContext.Request["Token"] != "dhbjdhb")
                        throw new Exception("Invalid Token");
                    var EncryptionType = (EncryptionType)Enum.Parse(typeof(EncryptionType), currentContext.Request["EncryptionType"]);

                    var site = new DAOBasic();
                    try
                    {
                        site.BeginTrans();
                        var s = currentContext.Request["EncryptTableColumn"];
                        var tableColumns = s.Split('|');
                        foreach (var tableColumn in tableColumns)
                        {
                            var ss = tableColumn.Split(':');
                            Util.ChangeColumnEncryption(site, ss[0], ss[1], EncryptionType.None, EncryptionType);
                        }
                        site.Commit();
                    }
                    catch (Exception ex)
                    {
                        site.RollBack();
                        throw;
                    }
                    finally
                    {
                        site.Close();
                    }

                }
                else if (currentContext.Request["GetDOCX"] != null)
                {
                    try
                    {
                        Thread.CurrentThread.Priority = ThreadPriority.Lowest;
                        var GetDOCXParams = currentContext.Request["GetDOCXParams"].Split(new string[] { AppPress.QuerySeperator }, StringSplitOptions.None);
                        string tempFolder = null;
                        if (GetDOCXParams.Count() > 1)
                        {
                            tempFolder = GetTemporaryDirectory();
                            currentContext.Response.ContentType = "Application/zip";
                        }
                        else
                            currentContext.Response.ContentType = "application/docx";
                        foreach (var GetDOCXParam in GetDOCXParams)
                        {
                            var pdfParams = GetDOCXParam.Split(new string[] { AppPress.QuerySeperator1 }, StringSplitOptions.None);
                            var formName = AppPress.formDefs.Find(t => t.id == long.Parse(pdfParams[0])).formName;
                            var id = pdfParams[1];
                            var docxFileName = HttpUtility.UrlDecode(pdfParams[2]);
                            var fileName = pdfParams[3];
                            if (fileName.IsNullOrEmpty())
                                fileName = formName;
                            else
                                fileName = HttpUtility.UrlDecode(fileName);
                            var docx = Util.GenerateDOCX(formName, id, currentContext.Request, docxFileName);
                            if (tempFolder == null)
                            {
                                currentContext.Response.AddHeader("content-disposition", "attachment; filename=\"" + fileName + ".docx\"");
                                currentContext.Response.BinaryWrite(docx);
                            }
                            else
                                File.WriteAllBytes(tempFolder + "\\" + fileName + ".docx", docx);
                        }
                        if (tempFolder != null)
                        {
                            var zipfileName = Path.GetTempFileName();
                            File.Delete(zipfileName);
                            ZipFile.CreateFromDirectory(tempFolder, zipfileName);
                            currentContext.Response.AddHeader("content-disposition", "attachment; filename=\"" + Path.GetFileNameWithoutExtension(zipfileName) + ".zip\"");
                            currentContext.Response.BinaryWrite(File.ReadAllBytes(zipfileName));
                        }
                        currentContext.Response.AddHeader("Cache-Control", "no-store; no-cache");
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                        currentContext.Response.Flush();
                        currentContext.Response.Close();
                    }
                    catch (Exception ex)
                    {
                        currentContext.Response.Clear();
                        currentContext.Response.ClearHeaders();
                        currentContext.Response.ContentType = "text/plain";
                        currentContext.Response.Write(ex.Message);
                    }
                    finally
                    {
                        //currentContext.Response.Redirect(currentContext.Request.UrlReferrer.ToString(), true);
                    }
                }
                else if (currentContext.Request["GetPDF"] != null)
                {
                    try
                    {
                        Thread.CurrentThread.Priority = ThreadPriority.Lowest;
                        var GetPDFParams = currentContext.Request["GetPDFParams"].Split(new string[] { AppPress.QuerySeperator }, StringSplitOptions.None);
                        string tempFolder = null;
                        if (GetPDFParams.Count() > 1)
                        {
                            tempFolder = GetTemporaryDirectory();
                            currentContext.Response.ContentType = "Application/zip";
                        }
                        else
                            currentContext.Response.ContentType = "application/pdf";
                        foreach (var GetPDFParam in GetPDFParams)
                        {
                            var pdfParams = GetPDFParam.Split(new string[] { AppPress.QuerySeperator1 }, StringSplitOptions.None);
                            var formName = AppPress.formDefs.Find(t => t.id == long.Parse(pdfParams[0])).formName;
                            var id = pdfParams[1];
                            var fileName = pdfParams[2];
                            if (fileName.IsNullOrEmpty())
                                fileName = formName;
                            else
                                fileName = HttpUtility.UrlDecode(fileName);
                            var pdf = Util.GeneratePDF(formName, id, currentContext.Request, appLogic);
                            if (tempFolder == null)
                            {
                                currentContext.Response.AddHeader("content-disposition", "attachment; filename=\"" + fileName + ".pdf\"");
                                currentContext.Response.BinaryWrite(pdf);
                            }
                            else
                                File.WriteAllBytes(tempFolder + "\\" + fileName + ".pdf", pdf);
                        }
                        if (tempFolder != null)
                        {
                            var zipfileName = Path.GetTempFileName();
                            File.Delete(zipfileName);
                            ZipFile.CreateFromDirectory(tempFolder, zipfileName);
                            currentContext.Response.AddHeader("content-disposition", "attachment; filename=\"" + Path.GetFileNameWithoutExtension(zipfileName) + ".zip\"");
                            currentContext.Response.BinaryWrite(File.ReadAllBytes(zipfileName));
                        }
                        currentContext.Response.AddHeader("Cache-Control", "no-store; no-cache");
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                        currentContext.Response.Flush();
                        currentContext.Response.Close();
                    }
                    catch (Exception ex)
                    {
                        currentContext.Response.Clear();
                        currentContext.Response.ClearHeaders();
                        currentContext.Response.ContentType = "text/plain";
                        currentContext.Response.Write(ex.Message);
                    }
                    finally
                    {
                        //currentContext.Response.Redirect(currentContext.Request.UrlReferrer.ToString(), true);
                    }
                }
                else if (currentContext.Request["GetCode"] != null)
                {
                    currentContext.Response.Clear();
                    currentContext.Response.ClearHeaders();
                    currentContext.Response.ContentType = "text/html";
                    var formDef = AppPress.FindFormDef(currentContext.Request["Form"]);
                    var code = formDef.GenerateCode();
                    currentContext.Response.Write(code);
                }
                else if (currentContext.Request["GetLocalization"] != null)
                {
                    currentContext.Response.Clear();
                    currentContext.Response.ClearHeaders();
                    currentContext.Response.ContentType = "text/html";
                    var formDefs = AppPress.formDefs;

                    var LExitingKeys = new Dictionary<string, string>();
                    foreach (var formDef in formDefs)
                    {
                        var LKeys = formDef.GenerateLocalizationKey(LExitingKeys);
                        foreach (var key in LKeys.Keys)
                        {
                            if (!AppPress.LocalizationData.ContainsKey(key))
                                LExitingKeys.Add(key, LKeys[key]);
                        }
                    }
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine("<table cellpadding=\"0\" cellspacing=\"3\" border=\"1\"><tr><th>Key</th><th>English</th></tr>");
                    foreach (var key in LExitingKeys.Keys)
                    {
                        sb.AppendLine("<tr><td>" + key + "</td><td>" + LExitingKeys[key] + "</td></tr>");

                    }
                    sb.AppendLine("</table>");
                    currentContext.Response.Write(sb.ToString());
                }
                else if (currentContext.Request["GetFile"] != null)
                {
                    var dbName = currentContext.Request["DBName"];
                    var FilePath = currentContext.Request["FilePath"];
                    var fileId = currentContext.Request["Id"];
                    var heightStr = currentContext.Request["height"];
                    var widthStr = currentContext.Request["width"];
                    var downloadStr = currentContext.Request["Download"];
                    var responseInstanceId = currentContext.Request["ResponseInstanceId"];
                    var download = !string.IsNullOrWhiteSpace(downloadStr);

                    FileDetails fileDetails = new FileDetails();
                    var instanceId = currentContext.Request["InstanceId"];
                    if (instanceId != null)
                    {
                        var remoteUrl = AppPress.Settings.Instances.Find(t => t.InstanceId == int.Parse(instanceId)).InstanceBaseUrl + "?GetFile=" + "&ResponseInstanceId=" + AppPress.LocalInstanceId + "&Id=" + fileId;
                        if (FilePath != null)
                            remoteUrl += "&FilePath=" + FilePath;
                        if (heightStr != null)
                            remoteUrl += "&height=" + heightStr;
                        if (widthStr != null)
                            remoteUrl += "&width=" + widthStr;
                        if (downloadStr != null)
                            remoteUrl += "&Download=" + downloadStr;

                        WebClient client = new WebClient();
                        var fileResponseStr = System.Text.Encoding.UTF8.GetString(client.UploadValues(new Uri(remoteUrl), new NameValueCollection()));
                        fileDetails = (FileDetails)FormDef.Deserialize(fileResponseStr, typeof(FileDetails));
                    }
                    else
                    {
                        var url = HttpUtility.UrlDecode(currentContext.Request.Url.ToString());
                        var sData = SessionData.TryGetSessionData();
                        var site = new DAOBasic();
                        try
                        {
                            if (dbName == null)
                                dbName = site.dbName;
                            if (DAOBasic.databaseType == DatabaseType.SqlServer)
                                dbName += ".dbo";
                            if (fileId != null)
                                if (site.ExecuteInt("Select Used From " + dbName + ".Application_Files Where Id=" + fileId) == 0)
                                    throw new Exception("File with Id: " + fileId + " is marked as not Used. So cannot be served");
                            if (sData == null || sData.formDefIdAndFormIds.Find(t => t == url) == null)
                                if (fileId == null || site.ExecuteInt("Select NonSecure From " + dbName + ".Application_Files Where Id=" + fileId) == 0)
                                    // File Request for Employee Photo come from URL from PDF and Org Chart
                                    throw new Exception("Security Error: Invalid access");



                            string fileName;
                            string fileContentType;
                            DateTime uploadTime;

                            if (fileId != null)
                                fileDetails.FileBytes = Util.GetFile(site, dbName, int.Parse(fileId), out fileName, out fileContentType, out uploadTime);
                            else
                            {
                                fileName = Path.GetFileName(FilePath);
                                uploadTime = File.GetCreationTime(FilePath);
                                fileContentType = "";
                                fileDetails.FileBytes = File.ReadAllBytes(FilePath);
                            }

                            fileDetails.FileName = fileName;
                            fileDetails.UploadTime = uploadTime;
                            fileDetails.ContentType = fileContentType;

                        }
                        finally
                        {
                            site.Close();
                        }
                        byte[] newbuffer = fileDetails.FileBytes;
                        if (!download && fileDetails.ContentType.ToLower().Contains("image"))
                        {
                            int height = int.Parse(heightStr ?? "-1");
                            int width = int.Parse(widthStr ?? "-1");

                            if (width == -1 && height == -1)
                                newbuffer = fileDetails.FileBytes;
                            else
                            {
                                MemoryStream ms = new MemoryStream(fileDetails.FileBytes);
                                Image img = Image.FromStream(ms);
                                if (width == -1)
                                    width = (int)(height * ((double)img.Width / img.Height));
                                if (height == -1)
                                    height = (int)(width * ((double)img.Height / img.Width));
                                using (Bitmap newImage = new Bitmap(width * 2, height * 2, PixelFormat.Format32bppArgb))
                                {
                                    using (Graphics canvas = Graphics.FromImage(newImage))
                                    {
                                        canvas.SmoothingMode = SmoothingMode.AntiAlias;
                                        canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
                                        canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
                                        canvas.Clear(System.Drawing.Color.Transparent);
                                        canvas.DrawImage(img, new Rectangle(new Point(0, 0), new Size(width * 2, height * 2)));
                                        MemoryStream m = new MemoryStream();
                                        newImage.Save(m, ImageFormat.Jpeg);
                                        newbuffer = m.ToArray();
                                    }
                                }
                            }
                        }
                        fileDetails.FileBytes = newbuffer;
                    }
                    if (fileDetails.FileBytes != null)
                    {
                        //currentContext.Response.Clear(); RAM???:Giviing access denied errro from remote.
                        if (responseInstanceId == null)
                        {
                            currentContext.Response.Clear();
                            currentContext.Response.BinaryWrite(fileDetails.FileBytes);
                            currentContext.Response.ContentType = download ? "application/force-download" : fileDetails.ContentType;
                            currentContext.Response.Cache.SetCacheability(HttpCacheability.Public);
                            currentContext.Response.Cache.SetLastModified(fileDetails.UploadTime);
                            currentContext.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + fileDetails.FileName.Replace("\"", "\\\"") + "\"");
                        }
                        else
                        {
                            var s = FormDef.Serialize(fileDetails, typeof(FileDetails));
                            currentContext.Response.Write(s);
                        }
                    }


                }
                else if (currentContext.Request["getExcel"] != null)
                {
                    var site = new DAOBasic();
                    try
                    {
                        var viewQuery = currentContext.Request["viewQuery"];
                        var sheetNames = currentContext.Request["sheetNames"];
                        List<string> sheetList = new List<string>();
                        if (!sheetNames.IsNullOrEmpty())
                        {
                            string[] sheets = sheetNames.Split(new string[] { AppPress.QuerySeperator }, StringSplitOptions.RemoveEmptyEntries);
                            foreach (var item in sheets)
                            {
                                sheetList.Add(item);
                            }
                        }
                        DataSet dataSet = site.ExecuteToGetDataSet(viewQuery);
                        string fileName = currentContext.Request["getExcel"];
                        bool isCreated = OfficeUtil.CreateExcelDocumentAsStream(dataSet, fileName, currentContext.Response, sheetList);
                        if (!isCreated)
                        {
                            throw new AppPressException("Fail to generate Excel Report.");
                        }
                    }
                    finally { site.Close(); }
                }
                else if (currentContext.Request["getCSV"] != null)
                {
                    var site = new DAOBasic();
                    try
                    {
                        currentContext.Response.ContentType = "application/CSV";
                        currentContext.Response.AddHeader("content-disposition", "attachment; filename=\"" + currentContext.Request["getCSV"] + ".csv\"");
                        var viewQuery = currentContext.Request["viewQuery"];

                        string csv = "";
                        if (viewQuery.Trim().StartsWith("Exec", StringComparison.InvariantCultureIgnoreCase) ||
                            viewQuery.Trim().StartsWith("Call", StringComparison.InvariantCultureIgnoreCase))
                        {
                            var spDr = site.ExecuteQuery(viewQuery);
                            try
                            {
                                for (int i = 0; i < spDr.FieldCount; i++)
                                {
                                    csv += @"""" + spDr.GetName(i).Replace("\"", "\"\"") + @""",";
                                }
                                csv = csv.Substring(0, csv.Length - 1) + "\r\n";
                                while (spDr.Read())
                                {
                                    for (int i = 0; i < spDr.FieldCount; i++)
                                    {
                                        csv += @"""" + spDr[i].ToString().Replace("\"", "\"\"") + @""",";
                                    }
                                    csv = csv.Substring(0, csv.Length - 1) + "\r\n";
                                }
                            }
                            finally
                            {
                                spDr.Close();
                            }
                        }
                        else
                        {
                            if (viewQuery.Contains(" "))
                                viewQuery = "(" + viewQuery + ")";
                            //add column Name
                            var qry = " Select * from " + viewQuery + " as bb";
                            var dr = site.ExecuteQuery(qry);
                            var selectColumns = "";
                            dr.Read();
                            try
                            {
                                string ifNull = "IfNull";
                                if (DAOBasic.databaseType == DatabaseType.SqlServer)
                                    ifNull = "IsNUll";
                                for (int i = 0; i < dr.FieldCount; i++)
                                {
                                    selectColumns += "" + ifNull + "(" + DAOBasic.SQLQuote + "" + dr.GetName(i) + "" + DAOBasic.SQLQuote + ",''),";
                                    csv += @"""" + dr.GetName(i).Replace("\"", "\"\"") + @""",";
                                }
                                selectColumns = selectColumns.Substring(0, selectColumns.Length - 1);
                                csv = csv.Substring(0, csv.Length - 1) + "\r\n";
                            }
                            finally
                            {
                                dr.Close();
                            }

                            qry = "Select " + selectColumns + " from " + viewQuery + " as bb";
                            dr = site.ExecuteQuery(qry);
                            try
                            {
                                while (dr.Read())
                                {
                                    for (int i = 0; i < dr.FieldCount; i++)
                                    {
                                        csv += @"""" + dr[i].ToString().Replace("\"", "\"\"") + @""",";
                                    }
                                    csv = csv.Substring(0, csv.Length - 1) + "\r\n";
                                }
                            }
                            finally
                            {
                                dr.Close();
                            }
                        }
                        currentContext.Response.Write(csv);
                    }
                    finally
                    {
                        site.Close();
                    }
                }
                else if (currentContext.Request["getHTMLTable"] != null)
                {
                    var url = HttpUtility.UrlDecode(currentContext.Request.Url.ToString());
                    var sData = SessionData.TryGetSessionData();
                    if (sData == null || sData.formDefIdAndFormIds.Find(t => t == url) == null)
                        throw new Exception("Security Error: Invalid access");
                    var site = new DAOBasic();
                    AppPress a = new AppPress(site);
                    a.Request = currentContext.Request;
                    currentContext.Response.ContentType = "text/HTML";
                    var qry = currentContext.Request["viewQuery"];
                    if (qry == null)
                        throw new Exception("Internal Error: Could not viewQuery in Post in ViewHTML");
                    var cssUrl = AppPress.GetBaseUrl() + Util.GetDefaultAspx() + "?getCSS=&filetime=" + DateTime.Now.Ticks;
                    var reportHeader = currentContext.Request["getHTMLTable"];
                    string html = @"<html><head><link rel=""stylesheet"" type=""text/css"" href=""" + cssUrl + @"""></head><body><div class=""appPressReport""><span style='text-weight:bold'>" + reportHeader + "</span>";

                    html += a.GetHtmlTableFromQuery(qry);
                    html += "<div></body></html>";
                    currentContext.Response.Write(html);
                }
                else if (currentContext.Request["GetSkin"] != null)
                {
                    var site = new DAOBasic();
                    AppPress a = new AppPress(site);
                    a.Request = currentContext.Request;
                    var oFormDefs = AppPress.formDefs;
                    try
                    {
                        AppPress.formDefs = AppPress.originalFormDefs;
                        currentContext.Response.Clear();
                        string str = "";
                        var formDef = AppPress.FindFormDef(currentContext.Request["Form"]);
                        formDef = Util.InitializeFormDef(a, formDef, AppPress.formDefs);
                        bool popup = currentContext.Request["Popup"] != null;
                        str += formDef.GenerateSkinTop(a, false, popup);
                        str += formDef.GenerateSkin(a, false, null);
                        str += formDef.GenerateSkinBottom(popup);
                        //try
                        //{
                        //    str = System.Xml.Linq.XElement.Parse("<AppPressHTMLRootNode>" + str + "</AppPressHTMLRootNode>").ToString();
                        //    str = str.Replace("<AppPressHTMLRootNode>", "").Replace("</AppPressHTMLRootNode>", "");
                        //}
                        //catch
                        //{
                        //    // isn't well-formed xml
                        //}
                        currentContext.Response.ContentType = "text/plain";
                        currentContext.Response.Write(str);

                    }
                    catch (Exception)
                    {
                        site.Close();
                        throw;
                    }
                    finally
                    {
                        AppPress.formDefs = oFormDefs;
                    }

                }
                else if (currentContext.Request["GetFO"] != null)
                {
                    var site = new DAOBasic();
                    AppPress a = new AppPress(site);

                    a.Request = currentContext.Request;
                    try
                    {

                        currentContext.Response.Clear();
                        string str = "";
                        var formDef = AppPress.FindFormDef(currentContext.Request["Form"]);
                        str += Util.FoHeaderStr + formDef.GenerateSkin(a, false, null) + Util.FoEndTag;
                        currentContext.Response.ContentType = "text/plain";
                        currentContext.Response.Write(str);

                    }
                    catch (Exception)
                    {
                        site.Close();
                    }

                }
                else if (HttpContext.Current.Request["RemoteForm"] != null)
                {
                    var site = new DAOBasic();
                    var formName = HttpContext.Current.Request["FormName"];
                    AppPress a = new AppPress(site);
                    AppPressResponse popup = null;
                    try
                    {
                        try
                        {
                            var formDef = AppPress.FindFormDef(formName);
                            if (formDef == null)
                                throw new Exception("Could not Find FormDef: " + formName);
                            var formDataId = HttpContext.Current.Request["FormDataId"];
                            PopupParams popupParams = null;
                            var popupParamsStr = HttpContext.Current.Request["PopupParams"];
                            if (popupParamsStr != null)
                                popupParams = (PopupParams)FormDef.Deserialize(popupParamsStr, typeof(PopupParams));
                            else
                                popupParams = new PopupParams();
                            a.remoteLoginUserId = HttpContext.Current.Request["RemoteLoginUserId"];
                            a.remoteInstanceId = a.instanceId = int.Parse(HttpContext.Current.Request["RemoteInstanceId"]);
                            a.remoteData = popupParams.remoteData;
                           
                            popupParams.forRedirect = HttpContext.Current.Request["Redirect"] != null;
                            popup = AppPressResponse.Popup(a, formDef, formDataId, popupParams);
                        }
                        catch (Exception ex)
                        {
                            popup = new AppPressResponse();
                            popup.appPressResponseType = AppPressResponseType.AlertMessage;
                            popup.message = ex.Message;
                        }
                       
                        a.appPressResponse.Add(popup);
                        var formDatas = a.formDatas;
                        var newFormDatas = new List<FormData>();
                        a.remoteFormDefs = new List<FormDef>();
                        for (int i = 0; i < formDatas.Count(); ++i)
                        {
                            newFormDatas.Add(new FormData(formDatas[i]));
                            a.remoteFormDefs.Add(formDatas[i].formDef);
                        }

                        a.formDatas = new List<FormData>();
                        foreach (var formData in newFormDatas)
                        {
                            if (formData.IsDeleted && formData.IsNew)
                                continue;
                            var fieldValues = formData.SerializableFields(a);
                            if (fieldValues.Count() == 0)
                                if (formData.formDef.formFields.Find(t => t.Type == FormDefFieldType.FormContainerDynamic || t.Type == FormDefFieldType.Button) == null)
                                    continue;
                            formData.fieldValues = fieldValues;
                            a.formDatas.Add(formData);
                        }
                        HttpContext.Current.Response.Write(FormDef.Serialize(a, typeof(AppPress)));
                        a.remoteFormDefs = null;
                        a.formDatas = formDatas;
                    }
                    finally
                    {
                        site.Close();
                    }
                }
                else if (HttpContext.Current.Request["functionCall"] != null)
                {
                    Util.AjaxCallHandler(currentContext.Request, currentContext.Response, appLogic); // Ajax Call Handler ---
                }
                else if (currentContext.Request["Form"] != null || currentContext.Request["FormDef"] != null) //FormDef should be removed once Mubeen is updated
                {
                    var site = new DAOBasic();
                    var formName = currentContext.Request["Form"] ?? currentContext.Request["FormDef"];
                    var id = currentContext.Request["id"] == null ? AppPress.GetUniqueId().ToString() : currentContext.Request["id"];
                    try
                    {
                        try
                        {
                            var a = new AppPress(site, currentContext.Request, currentContext.Response, formName, id, SkinType.HTML);
                            a.ignoreSkin = currentContext.Request["ignoreSkin"] != null;
                            var SkinFileName = currentContext.Request["SkinFileName"];
                            string skin = null;
                            string formUIStr = null;
                            if (SkinFileName != null)
                            {
                                a.URLFormName = formName;
                                a.SkinFileName = SkinFileName;
                            }
                            var rootFormDatas = a.formDatas.FindAll(t => t.formDef.formName == formName);
                            if (rootFormDatas.Count() != 1)
                                throw new Exception("Found 0 or more than 1 Forms: " + formName);
                            var rootFormData = rootFormDatas[0];
                            if (rootFormData.formDef.MasterFormName != null)
                            {
                                rootFormDatas = a.formDatas.FindAll(t => t.formDefId == AppPress.FindFormDef(rootFormData.formDef.MasterFormName).id);
                                if (rootFormDatas.Count() != 1)
                                    throw new Exception("Found 0 or more than 1 Forms: " + rootFormData.formDef.MasterFormName);
                                rootFormData = rootFormDatas[0];
                            }
                            formUIStr = rootFormData.GetHtml(a, false, false, skin, SkinType.HTML);
                            formUIStr = Util.RemoveScripts(a, formUIStr);
                            currentContext.Response.Clear();
                            currentContext.Response.ContentType = "text/html";
                            currentContext.Response.Write(formUIStr);
                        }
                        catch (SessionExpiredException)
                        {
                            throw;
                        }
                        catch (ThreadAbortException)
                        {
                            throw;
                        }
                        catch (Exception ex)
                        {
                            if (formName != "ErrorForm" && AppPress.formDefs != null && formName != AppPress.Settings.SessionExpiredRedirectForm)
                            {
                                CustomizeException xEx = new CustomizeException();
                                xEx.Message = ex.Message;
                                xEx.StackTrace = ex.StackTrace;

                                if (ex.InnerException != null)
                                {
                                    xEx.InnerExMessage1 = ex.InnerException.Message;
                                    xEx.InnerExStackTrace1 = ex.InnerException.StackTrace;
                                }
                                if (ex.InnerException != null && ex.InnerException.InnerException != null)
                                {
                                    xEx.InnerExMessage2 = ex.InnerException.InnerException.Message;
                                    xEx.InnerExStackTrace2 = ex.InnerException.InnerException.StackTrace;
                                }

                                var a = new AppPress();
                                var url = a.GetUrl("ErrorForm", null, null, null);
                                if (a.Request != null)
                                {
                                    System.Collections.Specialized.NameValueCollection tempPageUrl = null;
                                    if (a.Request.UrlReferrer != null)
                                        tempPageUrl = HttpUtility.ParseQueryString(a.Request.UrlReferrer.Query);
                                    if (tempPageUrl == null || tempPageUrl["HideRegions"] == null)
                                        tempPageUrl = HttpUtility.ParseQueryString(a.Request.Url.Query);
                                    if (tempPageUrl != null && tempPageUrl["HideRegions"] != null)
                                        url += "&HideRegions=" + tempPageUrl["HideRegions"];
                                }
                                if (id == "l")
                                    id = a.sessionData.loginUserId;
                                url += "&Message=" + HttpUtility.UrlEncode("Form: " + formName + ", Id: " + id);// + "Message: " + HttpUtility.HtmlDecode(ex.Message));

                                if (!a.sessionData.UserData.ContainsKey(AppPressKeys.ErrorFormException))
                                    a.sessionData.UserData.Add(AppPressKeys.ErrorFormException, xEx);
                                else
                                    a.sessionData.UserData[AppPressKeys.ErrorFormException] = xEx;
                                a.sessionData.AddSecureUrl(url);
                                a.Response.Redirect(url);
                            }
                            else
                                throw;

                        }
                    }
                    finally
                    {
                        site.Close();
                    }
                }
                else
                    throw new AppPressException("Invalid URL");
                Log.Writeln("Response: " + currentContext.Request.Url.AbsoluteUri);
            }
            catch (SessionExpiredException Ex)
            {
                string errorMsg = "Error: " + Ex.Message;
                if (Ex.InnerException != null)
                    errorMsg += ", InnerException: " + Ex.InnerException.Message;
                if (Ex.InnerException != null && Ex.InnerException.InnerException != null)
                    errorMsg += ", InnerInnerException: " + Ex.InnerException.InnerException.Message;
                Log.Writeln("Error: " + "Session Expired. " + errorMsg);
                Util.ErrorResponse(currentContext.Response, "Session Expired. " + errorMsg, Ex.StackTrace);
            }
            catch (Exception ex)
            {
                if (ex.GetType() != typeof(System.Threading.ThreadAbortException))
                {
                    string errorMsg1 = "Error: " + ex.Message;
                    if (ex.InnerException != null)
                        errorMsg1 += ", InnerException: " + ex.InnerException.Message;
                    if (ex.InnerException != null && ex.InnerException.InnerException != null)
                        errorMsg1 += ", InnerInnerException: " + ex.InnerException.InnerException.Message;
                    Log.Writeln("Error: " + errorMsg1 + "     StackTrace: " + ex.StackTrace);
                    Util.ErrorResponse(currentContext.Response, ex.Message, ex.StackTrace);
                }
            }
        }



    }
}
